<?php
/**
 * Finist
 *
 * Обработка данных статей
 *
 * @author Дмитрий Кузьма <kouzma.d@gmail.com>
 * @version 1.0
 */
class Finist extends ActiveRecord  {
	protected $tableName = 'finist';
	public $pkName = 'ID_finist';
	

	/**
	 * Парсит данные файла. Принимает уже строковое значение
	 * 
	 * @param string $fileContent - текст файла финиста
	 * @return boolean
	 */
	public function parseFileContent($fileContent) {
		Service_Debug::setDebug();
		if (empty($fileContent)) return false;
		
		// Создаем массив строк и проходим по строкам файла
		$arrLines = explode("\n", $fileContent);
		foreach ($arrLines as $key=> $strLine) {
			if (!$key) continue; // Первую строку пропускаем
			$arrLine = explode(";", $strLine);
			if (empty($arrLine[2])) continue; // Если это просто заготовка, то пропускаем строку
			if (empty($arrLine[0])) { // Если первый столбец пуст, значит файл закончился
				break;
			}
			$this->_parseFileRow($arrLine);
		}
	}
	
	
	/**
	 * Парсит конкретную строку файла финист
	 * 
	 * @param array $arrLine - конкретная строка файла финист
	 */
	private function _parseFileRow(array $arrLine) {
		Service_Debug::setDebug();
		if (!$arrLine) return false;
		$objDB = Service_Database::instance();

		$stmt = "INSERT INTO `finist` (
				`a`," // 0
		. "`date_str`," // 1
		. "`company`," // 2
		. "`driver`," // 3
		. "`place_start`," // 4
		. "`place_finish`," // 5
		. "`time_str`," // 6
		. "`time_finish_str`," // 7
		. "`time_duration_str`," // 8
		. "`price_our_hour`," // 9
		. "`price_our`," // 10
		. "`price_client_hour`," // 11
		. "`price_client`," // 12
		. "`profit`," // 13
		. "`pay_date_str`," // 14
		. "`comment`," // 15
		. "`pay_type`," // 16
		. "`car_category`," // 17
		. "`manager`," // 18
		. "`logist`," // 19
		. "`payed`," // 20
		. "`pay_type_driver`," // 21
		. "`card`," // 22
		. "`driver_pay_date_str`," // 23
		. "`multy_city`," // 24
		. "`additional_comment`," // 25
		. "`changes_date_str`," // 26
		. "`date`," // 27
		. "`pay_date`" // 28
		. ")
      VALUES (
				'" . Service_Escape::absolutelyEscapeString($arrLine[0]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[1]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[2]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[3]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[4]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[5]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[6]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[7]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[8]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[9]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[10]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[11]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[12]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[13]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[14]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[15]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[16]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[17]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[18]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[19]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[20]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[21]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[22]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[23]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[24]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[25]) . "',
				'" . Service_Escape::absolutelyEscapeString($arrLine[26]) . "',
				'" . Service_Date::humanDateToBD(Service_Escape::absolutelyEscapeString($arrLine[1])) . "',
				'" . Service_Date::humanDateToBD(Service_Escape::absolutelyEscapeString($arrLine[14])) . "'
			) ";
		$objDB->query($stmt);
		//echo $stmt;
	}
	
	/**
	 * Получает статистику за определенный месяц или всю, если месяц не задан
	 * 
	 * @param staring $date - дата в формате БД, соответствующая началу месяца, за который получается статистика
	 */
	public function getStat($date = null) {
		Service_Debug::setDebug();
		$stmtDatesConditions = '1 ';
		if ($date) {
			$endMonth = date('Y-m-t',Service_Date::getTimestamp($date));
			$stmtDatesConditions = "`finist`.`date` >= '" . $date . "' AND `finist`.`date` <= '" . $endMonth . "'";
		}
		$stmt = "SELECT 
			COUNT(`finist`.`ID_finist`) AS `orders_amount`,
			SUM(`finist`.`profit`) AS `total_profit`
		FROM `finist`
		WHERE " . $stmtDatesConditions . "
		";
		$objDB = Service_Database::instance();
		$arrData = $objDB->selectOne($stmt);
		if (!$arrData['orders_amount']) return array();
		return $arrData;
	}
	
	
	/**
	 * Получает статистику по менеджерам
	 * 
	 * @param string $dateStart - дата в формате БД, соответствующая началу периода
	 * @param string $dateStop - дата в формате БД, соответствующая завершению периода
	 * 
	 * @return array - массив со статистикой по менеджерам
	 */
	public function getManagersStat($dateStart = null, $dateStop = null) {
		Service_Debug::setDebug();
		$stmtDatesConditions = '1 ';
		if ($dateStart) {
			$stmtDatesConditions = " `finist`.`date` >= '" . $dateStart . "' "; 
			if ($dateStart) $stmtDatesConditions .= " AND `finist`.`date` <= '" . $dateStop . "'";
		}
		$stmt = "SELECT 
			COUNT(`finist`.`ID_finist`) AS `orders_amount`,
			SUM(`finist`.`profit`) AS `total_profit`,
			`finist`.`ID_manager`, `finist`.`manager`
		FROM `finist`
		WHERE " . $stmtDatesConditions . "
		GROUP BY `finist`.`manager`
		ORDER BY `total_profit` DESC 
		";
		$objDB = Service_Database::instance();
		$arrData = $objDB->select($stmt);
		return $arrData;
	}
	
	/**
	 * Получает статистику по разбве о ценам
	 * 
	 * @param string $dateStart - дата в формате БД, соответствующая началу периода
	 * @param string $dateStop - дата в формате БД, соответствующая завершению периода
	 * 
	 * @return array - массив со статистикой по типам машин
	 */
	public function getPriceTypesStat($dateStart = null, $dateStop = null) {
		Service_Debug::setDebug();
		$stmtDatesConditions = '1 ';
		if ($dateStart) {
			$stmtDatesConditions = " `finist`.`date` >= '" . $dateStart . "' "; 
			if ($dateStart) $stmtDatesConditions .= " AND `finist`.`date` <= '" . $dateStop . "'";
		}
		$stmt = "SELECT 
			COUNT(`finist`.`ID_finist`) AS `orders_amount`,
			SUM(`finist`.`profit`) AS `total_profit`,
			IF (
				`finist`.`profit` <= 0, 
				'0', 
				IF (
					`finist`.`profit` <= 150, 
					'1-150',
					IF (
						`finist`.`profit` <= 300, 
						'151-300',
						IF (
							`finist`.`profit` <= 450, 
							'301-450',
							IF (
								`finist`.`profit` <= 550, 
								'451-550',
								IF (
									`finist`.`profit` <= 700, 
									'551-700',
									IF (
										`finist`.`profit` <= 900, 
										'701-900',									
										IF (
											`finist`.`profit` <= 1350, 
											'901-1350',
											IF (
												`finist`.`profit` <= 2000, 
												'1351-2000',
												IF (
													`finist`.`profit` <= 3500, 
													'2001-3500',
													'3501-'
												)
											)
										)
									)
								)
							)
						)				
					)
				)
			) AS `price_type`
		FROM `finist`
		WHERE " . $stmtDatesConditions . "
		GROUP BY `price_type`
		ORDER BY `total_profit` DESC 
		";
		$objDB = Service_Database::instance();
		$arrData = $objDB->select($stmt);
		return $arrData;
	}
	
	/**
	 * Получает статистику по дням
	 *
	 * @param string $dateStart - дата в формате БД, соответствующая началу периода
	 * @param string $dateStop - дата в формате БД, соответствующая завершению периода
	 *
	 * @return array - массив со статистикой по дням
	 */
	public function getDaysStat($dateStart = null, $dateStop = null) {
		Service_Debug::setDebug();
		$stmtDatesConditions = '1 ';
		if ($dateStart) {
			$stmtDatesConditions = " `finist`.`date` >= '" . $dateStart . "' ";
			if ($dateStart) $stmtDatesConditions .= " AND `finist`.`date` <= '" . $dateStop . "'";
		}
		$stmt = "SELECT
			COUNT(`finist`.`ID_finist`) AS `orders_amount`,
			SUM(`finist`.`profit`) AS `total_profit`,
			`finist`.`date`
		FROM `finist`
		WHERE " . $stmtDatesConditions . "
		GROUP BY `date`
		ORDER BY `date` ASC
		";
		$objDB = Service_Database::instance();
		$arrData = $objDB->select($stmt);
		return $arrData;
	}
	
	/**
	 * Получает статистику по дням недели
	 *
	 * @param string $dateStart - дата в формате БД, соответствующая началу периода
	 * @param string $dateStop - дата в формате БД, соответствующая завершению периода
	 *
	 * @return array - массив со статистикой по дням недели
	 */
	public function getWeekDaysStat($dateStart = null, $dateStop = null) {
		Service_Debug::setDebug();
		$stmtDatesConditions = '1 ';
		if ($dateStart) {
			$stmtDatesConditions = " `finist`.`date` >= '" . $dateStart . "' ";
			if ($dateStart) $stmtDatesConditions .= " AND `finist`.`date` <= '" . $dateStop . "'";
		}
		$stmt = "SELECT
			COUNT(`finist`.`ID_finist`) AS `orders_amount`,
			SUM(`finist`.`profit`) AS `total_profit`,
			WEEKDAY(`finist`.`date`) AS `week_day`,
			(TIMESTAMPDIFF(WEEK, MIN(`finist`.`date`), MAX(`finist`.`date`)) + 1) AS `weeks`
		FROM `finist`
		WHERE " . $stmtDatesConditions . "
		GROUP BY `week_day`
		ORDER BY `week_day` ASC
		";
		$objDB = Service_Database::instance();
		$arrData = $objDB->select($stmt);
		return $arrData;
	}
	
	/**
	 * Получает статистику по типам машин
	 * 
	 * @param string $dateStart - дата в формате БД, соответствующая началу периода
	 * @param string $dateStop - дата в формате БД, соответствующая завершению периода
	 * 
	 * @return array - массив со статистикой по типам машин
	 */
	public function getCarTypesStat($dateStart = null, $dateStop = null) {
		Service_Debug::setDebug();
		$stmtDatesConditions = '1 ';
		if ($dateStart) {
			$stmtDatesConditions = " `finist`.`date` >= '" . $dateStart . "' "; 
			if ($dateStart) $stmtDatesConditions .= " AND `finist`.`date` <= '" . $dateStop . "'";
		}
		$stmt = "SELECT 
			COUNT(`finist`.`ID_finist`) AS `orders_amount`,
			SUM(`finist`.`profit`) AS `total_profit`,
			`finist`.`car_category`
		FROM `finist`
		WHERE " . $stmtDatesConditions . "
		GROUP BY `finist`.`car_category`
		ORDER BY `total_profit` DESC 
		";
		$objDB = Service_Database::instance();
		$arrData = $objDB->select($stmt);
		return $arrData;
	}
	
	/**
	 * Получает статистику по компаниям
	 * 
	 * @param string $dateStart - дата в формате БД, соответствующая началу периода
	 * @param string $dateStop - дата в формате БД, соответствующая завершению периода
	 * @param string $order - тип сортирвки
	 * 
	 * @return array - массив со статистикой по копаниям
	 */
	public function getCompaniesStat($dateStart = null, $dateStop = null, $order = 'orders_amount') {
		Service_Debug::setDebug();
		$stmtDatesConditions = '1 ';
		if ($dateStart) {
			$stmtDatesConditions = " `finist`.`date` >= '" . $dateStart . "' "; 
			if ($dateStart) $stmtDatesConditions .= " AND `finist`.`date` <= '" . $dateStop . "'";
		}
		$stmt = "SELECT 
			COUNT(`finist`.`ID_finist`) AS `orders_amount`,
			SUM(`finist`.`profit`) AS `total_profit`,
			`finist`.`company`, `finist`.`ID_company`, `finist`.`manager`, `finist`.`ID_manager`
		FROM `finist`
		WHERE " . $stmtDatesConditions . "
		GROUP BY `finist`.`ID_company`
		ORDER BY `" . $order . "` DESC 
		";
		$objDB = Service_Database::instance();
		$arrData = $objDB->select($stmt);
		return $arrData;
	}
	
	
	
	/**
	 * Парсит компании в отдельную таблицу
	 * 
	 * @return int - возвращает количество добавленных компаний
	 */
	public function parseCompanies() {
		Service_Debug::setDebug();
		$objDB = Service_Database::instance();
		// Получаем список компаний, которые следует добавить
		$stmt = "SELECT DISTINCT `finist`.`company` FROM `finist`";
		$arrCompanies = $objDB->selectSimpleArray($stmt);
		$stmt = "SELECT `company`.`company_name` FROM `company`";
		$arrExistCompanies = $objDB->selectSimpleArray($stmt);
		$arrNewCompanies = array_diff($arrCompanies, $arrExistCompanies);

		foreach ($arrNewCompanies as $newCompanyName) {
			$stmt = "INSERT INTO `company` (`company_name`) VALUES('" . $newCompanyName . "');";
			$objDB->query($stmt);
		}
		
		return sizeof($arrNewCompanies);
		
	}
	
	/**
	 * Устанавливает связи на компанию для заказов
	 * 
	 * @return int - возвращает количество заказов, котыр проставлена ссылка на компанию
	 */
	public function setReferencesToCompanies() {
		Service_Debug::setDebug();
		$objDB = Service_Database::instance();
		// Получаем список компаний, которые следует добавить
		$stmt = "SELECT `company`.`ID_company`, `company`.`company_name` FROM `company`";
		$arrExistCompanies = $objDB->select($stmt);
		$k = 0;
		foreach ($arrExistCompanies as $arrCompany) {
			$stmt = "
				UPDATE `finist` 
				SET `finist`.`ID_company` = '" . $arrCompany['ID_company'] . "' 
				WHERE `finist`.`company` =  '" . $arrCompany['company_name'] . "'
			";
			$k += $objDB->query($stmt);
		}
		
		return $k;
		
	}
	
	/**
	 * Парсит менеджеров в отдельную таблицу
	 * 
	 * @return int - возвращает количество добавленных менеджеров
	 */
	public function parseManagers() {
		Service_Debug::setDebug();
		$objDB = Service_Database::instance();
		// Получаем список компаний, которые следует добавить
		$stmt = "SELECT DISTINCT `finist`.`manager` FROM `finist`";
		$arrManagers = $objDB->selectSimpleArray($stmt);
		$stmt = "SELECT `manager`.`manager_name` FROM `manager`";
		$arrExistManagers = $objDB->selectSimpleArray($stmt);
		$arrNewManagers = array_diff($arrManagers, $arrExistManagers);

		foreach ($arrNewManagers as $newManagerName) {
			$stmt = "INSERT INTO `manager` (`manager_name`) VALUES('" . $newManagerName . "');";
			$objDB->query($stmt);
		}
		
		return sizeof($arrNewManagers);
		
	}
	
	/**
	 * Устанавливает связи на менеджеров для заказов
	 * 
	 * @return int - возвращает количество заказов, которым была проставлена ссылка на менеджера
	 */
	public function setReferencesToManagers() {
		Service_Debug::setDebug();
		$objDB = Service_Database::instance();
		// Получаем список компаний, которые следует добавить
		$stmt = "SELECT `manager`.`ID_manager`, `manager`.`manager_name` FROM `manager`";
		$arrExistManagers = $objDB->select($stmt);
		$k = 0;
		foreach ($arrExistManagers as $arrManager) {
			$stmt = "
				UPDATE `finist` 
				SET `finist`.`ID_manager` = '" . $arrManager['ID_manager'] . "' 
				WHERE `finist`.`manager` =  '" . $arrManager['manager_name'] . "'
			";
			$k += $objDB->query($stmt);
		}
		
		return $k;
		
	}
	

}
?>